# 模拟picarro数据 
import parse
import fire
import time
import datetime
import os
import random
import regex as re
from math import sin

# 输出log，便于调试
import logging

def update_data_dict_gen(t=None,mode='sin',selected_cols=None,data_types=None):
    """假造一些数据，返回字典格式
    """
    now_ts = time.time() if t is None else t # 默认当前时间
    update_data_dict = {}
    
    # 时间处理
    now_datetime = datetime.datetime.fromtimestamp(now_ts)
    jan1_datetime = datetime.datetime(year=now_datetime.year,month=1,day=1)
    dt_since_jan1 = now_datetime - jan1_datetime
    secs_since_jan1 = dt_since_jan1.total_seconds()

    # 时间赋值
    update_data_dict['DATE'] = now_datetime.strftime('%Y-%m-%d')
    update_data_dict["TIME"] = now_datetime.strftime('%H:%M:%S.%f')
    update_data_dict["FRAC_DAYS_SINCE_JAN1"] = secs_since_jan1/3600/24
    update_data_dict["FRAC_HRS_SINCE_JAN1"] = secs_since_jan1/3600
    update_data_dict["JULIAN_DAYS"] = secs_since_jan1/3600/24+1
    update_data_dict["EPOCH_TIME"] = now_ts

    # 生成数据
    if mode == 'sin':
        # 正弦变化的数据
        period = 100 # s
        shift = 10 # s
        for i,col in enumerate(selected_cols):
            if data_types[col][-1] in 'feg':
                update_data_dict[col] = 1000*(2+sin((now_ts+shift*i)/period))
                continue
            elif data_types[col][-1]  in 'd':
                update_data_dict[col] = int(1000*(1+sin((now_ts+shift*i)/period)))
                continue
            else :
                raise RuntimeError(f'unknown data type {col}:{data_types[col]}')
    elif mode == 'random':
        # 随机数据
        max = 1.0
        min = 0.0
        for i,col in enumerate(selected_cols):
            update_data_dict[col] = random.random()*(max-min)+min
    else:
        raise RuntimeError(f'mode={mode}, it must be "sin" or "random"')
    return update_data_dict

def main(output_filename= None,
        delay_time = 0.95,
        test_mode=False,
        max_time_hours = 24,
        mode='sin',
        log_level = 'INFO'):
    """假造一些输出到log文件，模拟实际设备
    """
    # 初始化
    logging.basicConfig(level = getattr(logging,log_level.upper(),logging.INFO)) # 默认info
    file_base_name = os.path.basename(__file__)
    logger = logging.getLogger(file_base_name)

    # header
    # 分隔符
    #sep = ' '
    
    col_width = 26 # 固定列宽格式
    # 列名
    header = 'DATE                      TIME                      FRAC_DAYS_SINCE_JAN1      FRAC_HRS_SINCE_JAN1       JULIAN_DAYS               EPOCH_TIME                ALARM_STATUS              INST_STATUS               CavityPressure            CavityTemp                DasTemp                   EtalonTemp                WarmBoxTemp               species                   MPVPosition               OutletValve               solenoid_valves           CO                        CO2                       CO2_dry                   CH4                       CH4_dry                   H2O                       h2o_reported              b_h2o_pct                 peak_14                   peak84_raw                '
        # 第一行
    logger.info(header)
    
    col_names = [header[i*col_width:i*col_width+col_width].strip() for i in range(len(header)//col_width)]
    # re.sub('[^a-zA-Z0-9]','_',n.strip())
    # 把'Temperature(°C)'转化为'Temperature__C_'

    # 非时间的类型
    # 尾部是STATUS的认为是
    types =['s']*2+ ['.8f','.6f','.8f','.3f'] + ['d' if col.endswith('STATUS') else '.10e' for col in col_names[6:]]

    # data types
    data_types =  dict(zip(col_names, types))
    
    data_write_formats = [f'<{col_width}{format}' for format in types] # >26s >26d >26.10e

    # selected cols
    selected_cols = col_names[6:] # skip all kinds of times
    
    # 默认值，为保持完整性
    defaults_str = '2020-12-04                22:15:31.657              339.26078308              8142.258794               340.26078308              1607120131.658            0                         963                       1.3999922362E+02          4.5000114441E+01          3.4212167406E+01          4.5304435730E+01          4.5000236511E+01          4.0000000000E+00          0.0000000000E+00          3.1923543297E+04          0.0000000000E+00          4.2624762096E-01          4.4728279991E+02          4.4962323590E+02          2.2627866372E+00          2.2725807459E+00          3.3528346203E-01          4.2964400486E-01          4.7567853250E-01          6.3450717542E+02          9.8725673361E-01          '


    # 生成格式化字符串
    line_write_formatter=''.join([f'{{{col_name}:{format}}}' for col_name,format in zip(col_names,data_write_formats)])
    logger.info(line_write_formatter)

    line_read_formatter=''.join([f'{{{col_name}:{format}}}' for col_name,format in zip(col_names,data_write_formats)])
    logger.info(line_read_formatter)

    # 输出文件名
    output_filename = output_filename if output_filename is not None else (file_base_name+r".test.log")

    with open(output_filename,'w+',encoding='utf-8') as OF:
        if test_mode: OF = None
        #header
        print(header,file=OF)
        #data lines
        start_time = time.time()
        data_dict = {}
        while(time.time()<start_time + max_time_hours*24*3600): # max hours
            update_data_dict = update_data_dict_gen(mode=mode,selected_cols=selected_cols,data_types=data_types)
            logger.info(update_data_dict)
            data_dict.update(update_data_dict)
            line = line_write_formatter.format(**data_dict)
            print(line,file=OF,flush=True)# flush is necessary
            time.sleep(delay_time)

if __name__ == "__main__":
    fire.Fire(main) # 利用fire命令行化
